<template>
  <div class="min-h-screen py-8 px-4 sm:px-6 lg:px-8">
    <div class="max-w-7xl mx-auto">
      <!-- 页面标题 -->
      <div class="text-center mb-12">
        <h1 class="text-4xl font-bold mb-4 tech-text">Performance API</h1>
        <p class="text-gray-300 text-lg">
          测量和分析网页性能，优化用户体验
        </p>
      </div>

      <!-- 浏览器支持提示 -->
      <div v-if="!isSupported" class="tech-card mb-8 border-yellow-600">
        <div class="flex items-center mb-4">
          <i class="i-carbon-warning text-yellow-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-yellow-500">浏览器支持提示</h3>
        </div>
        <p class="text-gray-300">
          您的浏览器不支持 Performance API。此功能需要现代浏览器支持。
        </p>
      </div>

      <!-- 导航时间 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">页面加载性能</h2>
        
        <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">DNS 查询</div>
            <div class="text-white text-2xl font-semibold">
              {{ navigationTiming.dns }}ms
            </div>
          </div>

          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">TCP 连接</div>
            <div class="text-white text-2xl font-semibold">
              {{ navigationTiming.tcp }}ms
            </div>
          </div>

          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">请求响应</div>
            <div class="text-white text-2xl font-semibold">
              {{ navigationTiming.request }}ms
            </div>
          </div>

          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">DOM 解析</div>
            <div class="text-white text-2xl font-semibold">
              {{ navigationTiming.domParsing }}ms
            </div>
          </div>

          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">资源加载</div>
            <div class="text-white text-2xl font-semibold">
              {{ navigationTiming.resourceLoading }}ms
            </div>
          </div>

          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">DOM 完成</div>
            <div class="text-white text-2xl font-semibold">
              {{ navigationTiming.domComplete }}ms
            </div>
          </div>

          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">页面加载完成</div>
            <div class="text-white text-2xl font-semibold">
              {{ navigationTiming.loadComplete }}ms
            </div>
          </div>

          <div class="bg-gray-800 rounded-lg p-4">
            <div class="text-gray-400 text-sm mb-1">总时间</div>
            <div class="text-white text-2xl font-semibold">
              {{ navigationTiming.total }}ms
            </div>
          </div>
        </div>

        <!-- 时间线可视化 -->
        <div class="bg-gray-800 rounded-lg p-6">
          <h3 class="text-white font-semibold mb-4">加载时间线</h3>
          <div class="space-y-3">
            <div
              v-for="phase in timelinePhases"
              :key="phase.name"
              class="flex items-center"
            >
              <div class="w-32 text-gray-400 text-sm">{{ phase.name }}</div>
              <div class="flex-1 relative h-8 bg-gray-700 rounded">
                <div
                  class="absolute h-full rounded transition-all duration-500"
                  :class="phase.color"
                  :style="{ width: `${phase.width}%`, left: `${phase.start}%` }"
                >
                  <span class="text-white text-xs px-2 leading-8">{{ phase.duration }}ms</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 资源性能 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">资源加载性能</h2>
        
        <div class="mb-6 flex gap-3">
          <button
            @click="loadResources"
            class="tech-button"
          >
            <i class="i-carbon-renew mr-2"></i>
            刷新资源数据
          </button>
          
          <select
            v-model="resourceFilter"
            class="bg-gray-800 text-white px-4 py-3 rounded-lg border border-gray-700"
          >
            <option value="all">所有资源</option>
            <option value="script">脚本</option>
            <option value="css">样式</option>
            <option value="img">图片</option>
            <option value="xmlhttprequest">XHR</option>
            <option value="fetch">Fetch</option>
          </select>
        </div>

        <div class="overflow-x-auto">
          <table class="w-full text-sm">
            <thead>
              <tr class="border-b border-gray-700">
                <th class="text-left py-3 px-4 text-gray-400 font-medium">资源名称</th>
                <th class="text-left py-3 px-4 text-gray-400 font-medium">类型</th>
                <th class="text-right py-3 px-4 text-gray-400 font-medium">大小</th>
                <th class="text-right py-3 px-4 text-gray-400 font-medium">时长</th>
                <th class="text-right py-3 px-4 text-gray-400 font-medium">开始时间</th>
              </tr>
            </thead>
            <tbody>
              <tr
                v-for="(resource, index) in filteredResources"
                :key="index"
                class="border-b border-gray-800 hover:bg-gray-800/50"
              >
                <td class="py-3 px-4 text-white max-w-md truncate" :title="resource.name">
                  {{ getResourceShortName(resource.name) }}
                </td>
                <td class="py-3 px-4 text-gray-300">
                  <span class="px-2 py-1 bg-gray-700 rounded text-xs">
                    {{ resource.initiatorType }}
                  </span>
                </td>
                <td class="py-3 px-4 text-gray-300 text-right">
                  {{ formatBytes(resource.transferSize) }}
                </td>
                <td class="py-3 px-4 text-gray-300 text-right">
                  {{ resource.duration.toFixed(2) }}ms
                </td>
                <td class="py-3 px-4 text-gray-400 text-right">
                  {{ resource.startTime.toFixed(2) }}ms
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <div v-if="filteredResources.length === 0" class="text-center py-8 text-gray-400">
          没有找到匹配的资源
        </div>
      </div>

      <!-- 自定义性能标记 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">自定义性能测量</h2>
        
        <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
          <!-- 创建标记 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h3 class="text-white font-semibold mb-4">创建性能标记</h3>
            
            <div class="space-y-4">
              <div>
                <label class="text-white font-medium mb-2 block">标记名称</label>
                <input
                  v-model="markName"
                  type="text"
                  placeholder="例如: task-start"
                  class="w-full bg-gray-700 text-white px-4 py-3 rounded-lg border border-gray-600 focus:border-tech-accent outline-none"
                >
              </div>

              <button
                @click="createMark"
                :disabled="!markName"
                class="tech-button w-full disabled:opacity-50 disabled:cursor-not-allowed"
              >
                <i class="i-carbon-add mr-2"></i>
                创建标记
              </button>
            </div>
          </div>

          <!-- 创建测量 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h3 class="text-white font-semibold mb-4">创建性能测量</h3>
            
            <div class="space-y-4">
              <div>
                <label class="text-white font-medium mb-2 block">测量名称</label>
                <input
                  v-model="measureName"
                  type="text"
                  placeholder="例如: task-duration"
                  class="w-full bg-gray-700 text-white px-4 py-3 rounded-lg border border-gray-600 focus:border-tech-accent outline-none"
                >
              </div>

              <div>
                <label class="text-white font-medium mb-2 block">开始标记</label>
                <select
                  v-model="measureStart"
                  class="w-full bg-gray-700 text-white px-4 py-3 rounded-lg border border-gray-600"
                >
                  <option value="">选择开始标记</option>
                  <option v-for="mark in marks" :key="mark.name" :value="mark.name">
                    {{ mark.name }}
                  </option>
                </select>
              </div>

              <div>
                <label class="text-white font-medium mb-2 block">结束标记</label>
                <select
                  v-model="measureEnd"
                  class="w-full bg-gray-700 text-white px-4 py-3 rounded-lg border border-gray-600"
                >
                  <option value="">选择结束标记（可选）</option>
                  <option v-for="mark in marks" :key="mark.name" :value="mark.name">
                    {{ mark.name }}
                  </option>
                </select>
              </div>

              <button
                @click="createMeasure"
                :disabled="!measureName || !measureStart"
                class="tech-button w-full disabled:opacity-50 disabled:cursor-not-allowed"
              >
                <i class="i-carbon-chart-line mr-2"></i>
                创建测量
              </button>
            </div>
          </div>
        </div>

        <!-- 标记列表 -->
        <div class="bg-gray-800 rounded-lg p-6 mb-6">
          <div class="flex justify-between items-center mb-4">
            <h3 class="text-white font-semibold">性能标记</h3>
            <button
              @click="clearMarks"
              class="text-red-400 hover:text-red-300 text-sm"
            >
              <i class="i-carbon-clean mr-1"></i>
              清空标记
            </button>
          </div>

          <div v-if="marks.length === 0" class="text-gray-400 text-center py-4">
            暂无性能标记
          </div>

          <div v-else class="grid grid-cols-1 md:grid-cols-2 gap-3">
            <div
              v-for="mark in marks"
              :key="mark.name"
              class="bg-gray-700 rounded-lg p-3 flex justify-between items-center"
            >
              <div>
                <div class="text-white font-medium">{{ mark.name }}</div>
                <div class="text-gray-400 text-sm">{{ mark.startTime.toFixed(2) }}ms</div>
              </div>
              <button
                @click="deleteMark(mark.name)"
                class="text-red-400 hover:text-red-300"
              >
                <i class="i-carbon-trash-can"></i>
              </button>
            </div>
          </div>
        </div>

        <!-- 测量列表 -->
        <div class="bg-gray-800 rounded-lg p-6">
          <div class="flex justify-between items-center mb-4">
            <h3 class="text-white font-semibold">性能测量</h3>
            <button
              @click="clearMeasures"
              class="text-red-400 hover:text-red-300 text-sm"
            >
              <i class="i-carbon-clean mr-1"></i>
              清空测量
            </button>
          </div>

          <div v-if="measures.length === 0" class="text-gray-400 text-center py-4">
            暂无性能测量
          </div>

          <div v-else class="space-y-3">
            <div
              v-for="measure in measures"
              :key="measure.name"
              class="bg-gray-700 rounded-lg p-4"
            >
              <div class="flex justify-between items-start mb-2">
                <div class="text-white font-medium">{{ measure.name }}</div>
                <button
                  @click="deleteMeasure(measure.name)"
                  class="text-red-400 hover:text-red-300"
                >
                  <i class="i-carbon-trash-can"></i>
                </button>
              </div>
              <div class="grid grid-cols-3 gap-4 text-sm">
                <div>
                  <span class="text-gray-400">开始时间:</span>
                  <span class="text-white ml-2">{{ measure.startTime.toFixed(2) }}ms</span>
                </div>
                <div>
                  <span class="text-gray-400">时长:</span>
                  <span class="text-white ml-2">{{ measure.duration.toFixed(2) }}ms</span>
                </div>
                <div>
                  <span class="text-gray-400">结束时间:</span>
                  <span class="text-white ml-2">{{ (measure.startTime + measure.duration).toFixed(2) }}ms</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 性能监视器 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">性能监视器</h2>
        
        <div class="bg-gray-800 rounded-lg p-6 mb-6">
          <div class="flex justify-between items-center mb-4">
            <h3 class="text-white font-semibold">实时性能指标</h3>
            <button
              @click="toggleMonitor"
              :class="isMonitoring ? 'bg-red-600 hover:bg-red-700' : 'bg-green-600 hover:bg-green-700'"
              class="text-white px-4 py-2 rounded-lg transition-colors"
            >
              <i :class="isMonitoring ? 'i-carbon-stop-filled' : 'i-carbon-play-filled'" class="mr-2"></i>
              {{ isMonitoring ? '停止监控' : '开始监控' }}
            </button>
          </div>

          <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
            <div class="bg-gray-700 rounded-lg p-4">
              <div class="text-gray-400 text-sm mb-1">内存使用</div>
              <div class="text-white text-xl font-semibold">
                {{ memoryUsage }}
              </div>
            </div>

            <div class="bg-gray-700 rounded-lg p-4">
              <div class="text-gray-400 text-sm mb-1">性能评分</div>
              <div class="text-white text-xl font-semibold">
                {{ performanceScore }}
              </div>
            </div>

            <div class="bg-gray-700 rounded-lg p-4">
              <div class="text-gray-400 text-sm mb-1">活动时长</div>
              <div class="text-white text-xl font-semibold">
                {{ formatDuration(activeTime) }}
              </div>
            </div>

            <div class="bg-gray-700 rounded-lg p-4">
              <div class="text-gray-400 text-sm mb-1">监控次数</div>
              <div class="text-white text-xl font-semibold">
                {{ monitorCount }}
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- API 信息 -->
      <div class="tech-card">
        <h3 class="text-xl font-semibold mb-4 text-white">API 信息</h3>
        <div class="space-y-4 text-gray-300">
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">浏览器支持</h4>
            <p>所有现代浏览器都支持 Performance API</p>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">主要接口</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">performance.timing</code> - 导航时间（已废弃）</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">performance.navigation</code> - 导航信息（已废弃）</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">PerformanceNavigationTiming</code> - 导航时间（新）</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">PerformanceResourceTiming</code> - 资源加载时间</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">performance.mark()</code> - 创建性能标记</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">performance.measure()</code> - 创建性能测量</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">performance.getEntries()</code> - 获取性能条目</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">性能指标</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><strong>FCP</strong> (First Contentful Paint) - 首次内容绘制</li>
              <li><strong>LCP</strong> (Largest Contentful Paint) - 最大内容绘制</li>
              <li><strong>FID</strong> (First Input Delay) - 首次输入延迟</li>
              <li><strong>CLS</strong> (Cumulative Layout Shift) - 累积布局偏移</li>
              <li><strong>TTFB</strong> (Time to First Byte) - 首字节时间</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">使用场景</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>页面加载性能分析</li>
              <li>资源加载优化</li>
              <li>用户体验监控</li>
              <li>性能瓶颈定位</li>
              <li>A/B 测试性能对比</li>
              <li>真实用户监控（RUM）</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">最佳实践</h4>
            <ul class="list-disc list-inside space-y-1 text-sm">
              <li>使用 PerformanceObserver 监听性能条目</li>
              <li>定期清理不需要的标记和测量</li>
              <li>结合 User Timing API 测量自定义操作</li>
              <li>使用 Resource Timing API 优化资源加载</li>
              <li>关注 Core Web Vitals 指标</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'

// 类型定义
interface NavigationTiming {
  dns: number
  tcp: number
  request: number
  domParsing: number
  resourceLoading: number
  domComplete: number
  loadComplete: number
  total: number
}

interface TimelinePhase {
  name: string
  duration: number
  start: number
  width: number
  color: string
}

// 响应式状态
const isSupported = ref('performance' in window)
const resourceFilter = ref('all')
const isMonitoring = ref(false)

// 导航时间
const navigationTiming = ref<NavigationTiming>({
  dns: 0,
  tcp: 0,
  request: 0,
  domParsing: 0,
  resourceLoading: 0,
  domComplete: 0,
  loadComplete: 0,
  total: 0
})

// 资源列表
const resources = ref<PerformanceResourceTiming[]>([])

// 自定义标记和测量
const markName = ref('')
const measureName = ref('')
const measureStart = ref('')
const measureEnd = ref('')
const marks = ref<PerformanceMark[]>([])
const measures = ref<PerformanceMeasure[]>([])

// 性能监控
const memoryUsage = ref('N/A')
const performanceScore = ref('N/A')
const activeTime = ref(0)
const monitorCount = ref(0)

let monitorInterval: ReturnType<typeof setInterval> | null = null
let startTime = 0

// 初始化
onMounted(() => {
  loadNavigationTiming()
  loadResources()
  loadMarksAndMeasures()
  startTime = performance.now()
})

// 清理
onUnmounted(() => {
  if (monitorInterval) {
    clearInterval(monitorInterval)
  }
})

// 加载导航时间
const loadNavigationTiming = () => {
  if (!isSupported.value) return

  try {
    const nav = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming

    if (nav) {
      navigationTiming.value = {
        dns: Math.round(nav.domainLookupEnd - nav.domainLookupStart),
        tcp: Math.round(nav.connectEnd - nav.connectStart),
        request: Math.round(nav.responseEnd - nav.requestStart),
        domParsing: Math.round(nav.domInteractive - nav.domLoading),
        resourceLoading: Math.round(nav.domComplete - nav.domContentLoadedEventEnd),
        domComplete: Math.round(nav.domComplete - nav.fetchStart),
        loadComplete: Math.round(nav.loadEventEnd - nav.fetchStart),
        total: Math.round(nav.loadEventEnd - nav.fetchStart)
      }
    }
  } catch (err) {
    console.error('加载导航时间失败:', err)
  }
}

// 时间线阶段
const timelinePhases = computed<TimelinePhase[]>(() => {
  const total = navigationTiming.value.total || 1
  const phases = [
    { name: 'DNS', duration: navigationTiming.value.dns, color: 'bg-blue-500' },
    { name: 'TCP', duration: navigationTiming.value.tcp, color: 'bg-green-500' },
    { name: '请求', duration: navigationTiming.value.request, color: 'bg-yellow-500' },
    { name: 'DOM 解析', duration: navigationTiming.value.domParsing, color: 'bg-orange-500' },
    { name: '资源加载', duration: navigationTiming.value.resourceLoading, color: 'bg-red-500' }
  ]

  let currentStart = 0
  return phases.map(phase => {
    const start = (currentStart / total) * 100
    const width = (phase.duration / total) * 100
    currentStart += phase.duration
    return {
      ...phase,
      start,
      width
    }
  })
})

// 加载资源
const loadResources = () => {
  if (!isSupported.value) return

  try {
    resources.value = performance.getEntriesByType('resource') as PerformanceResourceTiming[]
  } catch (err) {
    console.error('加载资源失败:', err)
  }
}

// 过滤资源
const filteredResources = computed(() => {
  if (resourceFilter.value === 'all') {
    return resources.value
  }
  return resources.value.filter(r => r.initiatorType === resourceFilter.value)
})

// 获取资源短名称
const getResourceShortName = (name: string): string => {
  try {
    const url = new URL(name)
    return url.pathname.split('/').pop() || name
  } catch {
    return name
  }
}

// 格式化字节
const formatBytes = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
}

// 创建标记
const createMark = () => {
  if (!markName.value) return

  try {
    performance.mark(markName.value)
    loadMarksAndMeasures()
    markName.value = ''
  } catch (err) {
    console.error('创建标记失败:', err)
    alert('创建标记失败')
  }
}

// 创建测量
const createMeasure = () => {
  if (!measureName.value || !measureStart.value) return

  try {
    if (measureEnd.value) {
      performance.measure(measureName.value, measureStart.value, measureEnd.value)
    } else {
      performance.measure(measureName.value, measureStart.value)
    }
    
    loadMarksAndMeasures()
    measureName.value = ''
    measureStart.value = ''
    measureEnd.value = ''
  } catch (err) {
    console.error('创建测量失败:', err)
    alert('创建测量失败')
  }
}

// 加载标记和测量
const loadMarksAndMeasures = () => {
  try {
    marks.value = performance.getEntriesByType('mark') as PerformanceMark[]
    measures.value = performance.getEntriesByType('measure') as PerformanceMeasure[]
  } catch (err) {
    console.error('加载标记和测量失败:', err)
  }
}

// 删除标记
const deleteMark = (name: string) => {
  try {
    performance.clearMarks(name)
    loadMarksAndMeasures()
  } catch (err) {
    console.error('删除标记失败:', err)
  }
}

// 删除测量
const deleteMeasure = (name: string) => {
  try {
    performance.clearMeasures(name)
    loadMarksAndMeasures()
  } catch (err) {
    console.error('删除测量失败:', err)
  }
}

// 清空标记
const clearMarks = () => {
  try {
    performance.clearMarks()
    loadMarksAndMeasures()
  } catch (err) {
    console.error('清空标记失败:', err)
  }
}

// 清空测量
const clearMeasures = () => {
  try {
    performance.clearMeasures()
    loadMarksAndMeasures()
  } catch (err) {
    console.error('清空测量失败:', err)
  }
}

// 切换监控
const toggleMonitor = () => {
  if (isMonitoring.value) {
    stopMonitor()
  } else {
    startMonitor()
  }
}

// 开始监控
const startMonitor = () => {
  isMonitoring.value = true
  
  monitorInterval = setInterval(() => {
    updateMonitorStats()
  }, 1000)
}

// 停止监控
const stopMonitor = () => {
  isMonitoring.value = false
  
  if (monitorInterval) {
    clearInterval(monitorInterval)
    monitorInterval = null
  }
}

// 更新监控统计
const updateMonitorStats = () => {
  monitorCount.value++
  activeTime.value = performance.now() - startTime

  // 内存使用
  if ('memory' in performance) {
    const mem = (performance as any).memory
    const used = mem.usedJSHeapSize / 1048576
    memoryUsage.value = `${used.toFixed(2)} MB`
  }

  // 性能评分（简化计算）
  const total = navigationTiming.value.total
  let score = 100
  if (total > 3000) score = 50
  else if (total > 2000) score = 70
  else if (total > 1000) score = 85
  performanceScore.value = score.toString()
}

// 格式化时长
const formatDuration = (ms: number): string => {
  const seconds = Math.floor(ms / 1000)
  const minutes = Math.floor(seconds / 60)
  const hours = Math.floor(minutes / 60)

  if (hours > 0) {
    return `${hours}h ${minutes % 60}m`
  } else if (minutes > 0) {
    return `${minutes}m ${seconds % 60}s`
  } else {
    return `${seconds}s`
  }
}
</script>

